import React, { useEffect, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import { Menu, Spin } from "antd";
import { findAllBreadcrumb, getOpenKeys, handleRouter, searchRoute } from "@/utils/util";
import { setMenuList } from "@/redux/feature/menuSlice";
import { setBreadcrumbList } from "@/redux/feature/breadSlice";
import { setAuthRouter, setPermissions } from "@/redux/feature/authSlice";
import { connect } from "react-redux";
import type { MenuProps } from "antd";
import * as Icons from "@ant-design/icons";
import Logo from "./components/Logo";
import "./index.less";
import { getMenuList } from "@/utils/api/modules/login";
import { loadRouterArray } from "@/routers";
import { RouteObject } from "@/routers/interface";
import { useTranslation } from "react-i18next";
import { RootState, useAppSelector } from "@/redux";

const LayoutMenu = (props: any) => {
	const { t } = useTranslation();
	const language = useAppSelector((state: RootState) => state.global.language)

	const { pathname } = useLocation();
	const { isCollapse, setBreadcrumbList, setAuthRouter, setPermissions, setMenuList: setMenuListAction } = props;
	const [selectedKeys, setSelectedKeys] = useState<string[]>([pathname]);
	const [openKeys, setOpenKeys] = useState<string[]>([]);

	// 刷新页面菜单保持高亮
	useEffect(() => {
		setSelectedKeys([pathname]);
		isCollapse ? null : setOpenKeys(getOpenKeys(pathname));
	}, [pathname, isCollapse]);

	// 设置当前展开的 subMenu
	const onOpenChange = (openKeys: string[]) => {
		if (openKeys.length === 0 || openKeys.length === 1) return setOpenKeys(openKeys);
		const latestOpenKey = openKeys[openKeys.length - 1];
		if (latestOpenKey.includes(openKeys[0])) return setOpenKeys(openKeys);
		setOpenKeys([latestOpenKey]);
	};

	// 定义 menu 类型
	type MenuItem = Required<MenuProps>["items"][number];
	const getItem = (
		label: React.ReactNode,
		key?: React.Key | null,
		icon?: React.ReactNode,
		children?: MenuItem[],
		type?: "group"
	): MenuItem => {
		return {
			key,
			icon,
			children,
			label,
			type,
		} as MenuItem;
	};

	// 动态渲染 Icon 图标
	const customIcons: { [key: string]: any } = Icons;
	const addIcon = (name: string) => {
		if (name) {
			return React.createElement(customIcons[name]);
		}
		return null;
	};

	// 处理后台返回菜单 key 值为 antd 菜单需要的 key 值
	const deepLoopFloat = (menuList: Menu.MenuOptions[], newArr: MenuItem[] = []) => {
		menuList.forEach((item: Menu.MenuOptions) => {
			// 下面判断代码解释 *** !item?.children?.length   ==>   (!item.children || item.children.length === 0)
			if (!item?.children?.length) return newArr.push(getItem(item.title, item.path, addIcon(item.icon!)));
			newArr.push(getItem(item.title, item.path, addIcon(item.icon!), deepLoopFloat(item.children)));
		});
		return newArr;
	};

	// 获取菜单列表并处理成 antd menu 需要的格式
	const [menuList, setMenuList] = useState<MenuItem[]>([]);
	const [loading, setLoading] = useState(false);
	const getMenuData = async () => {
		setLoading(true);
		try {
			let { data } = await getMenuList();
			if (!data) return;
			let menuArr = mergeMenu(data.menuArr);
			// 把按钮权限存储到 redux 中，做按钮权限判断
			setPermissions(data.permissionArr);
			console.log("menuArr", menuArr);
			setMenuList(deepLoopFloat(menuArr));
			// 存储处理过后的所有面包屑导航栏到 redux 中
			setBreadcrumbList(findAllBreadcrumb(menuArr));
			// 把路由菜单处理成一维数组，存储到 redux 中，做菜单权限判断
			const dynamicRouter = handleRouter(menuArr);
			setAuthRouter(dynamicRouter);
			setMenuListAction(data.menuArr);
		} catch (error) {
			console.log('menu error', error);
		} finally {
			setLoading(false);
		}
	};

	useEffect(() => {
		getMenuData();
	}, [language]);

	// 点击当前菜单跳转页面
	const navigate = useNavigate();
	const clickMenu: MenuProps["onClick"] = ({ key }: { key: string }) => {
		console.log('menuList', props.menuList)
		const route = searchRoute(key, props.menuList);
		if (route.isLink) window.open(route.isLink, "_blank");
		navigate(key);
	};

	function addMap(map: Map<any, any>, parentKey: string, itemArr: RouteObject[]) {
		itemArr.map((val) => {
			map.set(val.key, parentKey);
			if (val.children) {
				addMap(map, val.key, val.children);
			}
		});
	}
	const routeMap = () => {
		let map = new Map();
		let arr = loadRouterArray();
		arr.map((val) => {
			if (val.children) {
				addMap(map, val.key, val.children);
			}
		});

		return map;
	};
	function mergeMenu(data: string[]): Menu.MenuOptions[] {
		let res: Menu.MenuOptions[] = [];
		res.push({
			path: "/home/index",
			title: t("home.home"),
			key: "home",
			icon: "HomeOutlined",
		});
		let rMap = routeMap();
		let menuMap = new Map();
		data.map((val) => {
			menuMap.set(val, true);
			let curId = val;
			for (let i = 0; i < 10; i++) {
				let pid = rMap.get(curId);
				if (!pid) {
					break;
				}
				menuMap.set(pid, true);
				curId = pid;
			}
		});
		let menuArr = filterMenu(loadRouterArray(), menuMap);
		res = [...res, ...menuArr];
		return res;
	}
	function filterMenu(routerArr: RouteObject[], menuMap: Map<any, any>): Menu.MenuOptions[] {
		let arr: Menu.MenuOptions[] = [];
		routerArr.map((val) => {
			if (!menuMap.get(val.key)) {
				return;
			}
			let children: Menu.MenuOptions[] = [];
			if (val.children) {
				children = filterMenu(val.children, menuMap);
			}
			arr.push({ icon: val.icon, key: val.key, title: val.title, path: val.path || "", children: children });
		});
		return arr;
	}

	return (
		<div className="menu">
			<Spin spinning={loading} tip="Loading...">
				<Logo></Logo>
				<Menu
					theme="dark"
					mode="inline"
					triggerSubMenuAction="click"
					openKeys={openKeys}
					selectedKeys={selectedKeys}
					items={menuList}
					onClick={clickMenu}
					onOpenChange={onOpenChange}
				></Menu>
			</Spin>
		</div>
	);
};

const mapStateToProps = (state: any) => state.menu;
const mapDispatchToProps = { setMenuList, setBreadcrumbList, setAuthRouter, setPermissions };
export default connect(mapStateToProps, mapDispatchToProps)(LayoutMenu);
